package com.tiancikeji.zaoke.app.service.food.impl;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.tiancikeji.zaoke.app.dao.food.FoodNutritionDao;
import com.tiancikeji.zaoke.app.model.food.FoodNutrition;
import com.tiancikeji.zaoke.app.service.food.FoodNutritionService;
import com.tiancikeji.zaoke.app.util.LocalCaches;

@SuppressWarnings("unchecked")
public class FoodNutritionServiceImpl implements FoodNutritionService {

	private FoodNutritionDao foodNutritionDao;

	private long expireTime;

	public Set<FoodNutrition> getNutritionByFoodId(long foodId) {
		Set<Long> foodIds = new HashSet<Long>();
		foodIds.add(foodId);
		Map<Long, Set<FoodNutrition>> tags = getNutritionByFoodIds(foodIds);
		if(tags != null && tags.containsKey(foodId))
			return tags.get(foodId);
		return null;
	}

	public Map<Long, Set<FoodNutrition>> getNutritionByFoodIds(Set<Long> ids) {
		Map<Long, Set<FoodNutrition>> result = new HashMap<Long, Set<FoodNutrition>>();

		List<FoodNutrition> nutritions = getAllFoodNutritions();
		addNutritions(ids, result, nutritions);

		Set<Long> remainings = new HashSet<Long>();
		for (Long id : ids)
			if (!result.containsKey(id))
				remainings.add(id);

		if (remainings.size() > 0) {
			nutritions = foodNutritionDao.getNutritionsByFoodIds(remainings);
			addNutritions(ids, result, nutritions);
		}

		return result;
	}

	private void addNutritions(Set<Long> ids, Map<Long, Set<FoodNutrition>> result, List<FoodNutrition> nutritions) {
		if (nutritions != null && nutritions.size() > 0)
			for (FoodNutrition nutrition : nutritions)
				if (nutrition != null && ids.contains(nutrition.getFoodid())){
					Set<FoodNutrition> tagstmp = result.get(nutrition.getFoodid());
					if(tagstmp == null){
						tagstmp = new HashSet<FoodNutrition>();
						result.put(nutrition.getFoodid(), tagstmp);
					}
					tagstmp.add(nutrition);
				}
	}

	private List<FoodNutrition> getAllFoodNutritions() {
		List<FoodNutrition> tags = (List<FoodNutrition>) LocalCaches.get(LocalCaches.ZAOKE_CACHE_NUTRITIONS_KEY, System.currentTimeMillis(), expireTime);

		if (tags == null) {
			tags = foodNutritionDao.getAllNutritions();

			if (tags != null && tags.size() > 0)
				LocalCaches.set(LocalCaches.ZAOKE_CACHE_NUTRITIONS_KEY, tags, System.currentTimeMillis());
		}

		return tags;
	}

	public long getExpireTime() {
		return expireTime;
	}

	public void setExpireTime(long expireTime) {
		this.expireTime = expireTime;
	}

	public FoodNutritionDao getFoodNutritionDao() {
		return foodNutritionDao;
	}

	public void setFoodNutritionDao(FoodNutritionDao foodNutritionDao) {
		this.foodNutritionDao = foodNutritionDao;
	}

}
